import type { AxiosResponse } from 'axios'
import { serialize } from 'object-to-formdata'
import { type HttpResponse, request } from './base'
import { ref, watch } from 'vue'
import { useWebSocket } from '@vueuse/core'



export interface SignAudioDto {
  /**
   * 请求地址
   * @default 'iat-api.xfyun.cn'
   */
  host: string
  date: string
}

export interface SignAiDto {
  host: string
  date: string
}

export interface Message {
  content: string
  role: 'user' | 'assistant'
}

type APIReturn<T> = AxiosResponse<HttpResponse<T>>
/**
 * 讯飞语音听写Web API
 * @description 生成讯飞语音听写Web API的签名
 */
// async function generateAudioAuthorization(requestBody?: Partial<SignAudioDto>): Promise<APIReturn<string>> {
//   const body: SignAudioDto = {
//     host: 'iat-api.xfyun.cn',
//     date: new Date().toUTCString(),
//     ...requestBody,
//   }
//   const formData = serialize(body)
//   return await request.post('/audio/sign', formData)
// }

export async function getASRWebSocket(authorization: string) {
  const host = 'iat-api.xfyun.cn'
  const date = new Date().toUTCString()
  const content = ref('')
  const finished = ref(false)

  const ws = useWebSocket(`wss://avatar.cn-huadong-1.xf-yun.com/v1/interact?authorization=${authorization}&date=${date}&host=${host}`, {
    autoReconnect: true,
    onError(ws, event) {
      finished.value = true
      console.log('onError', event)
    },
  })

  watch(ws.data, (newVal) => {
    const res = JSON.parse(newVal)
    if (res.code === 0) {
      content.value += res.data.result.ws.reduce((result: string, item: { cw: { w: string }[] }) => result + item.cw.map((item: { w: string }) => item.w).join(''), '')
      // console.log(`receive message: ${content.value}`)
      // console.log(`status:${res.data.status}`)
      if (res.data.status === 2)
        finished.value = true
        // console.log('finished')
    }
    else { console.log(res) }
  })

  function send(data: string) {
    finished.value = false
    const body = {
      common: {
        app_id: 'bf00cb76',
      },
      business: {
        language: 'zh_cn',
        domain: 'iat',
        accent: 'mandarin',
        vad_eos: 8000,
      },
      data: {
        status: 0,
        format: 'audio/L16;rate=16000',
        encoding: 'raw',
        audio: data,
      },
    }
    ws.send(JSON.stringify(body))
  }

  function complete() {
    ws.send(
      JSON.stringify(
        {
          data: {
            status: 2,
          },
        },
      ),
    )
  }

  return {
    content,
    status: ws.status,
    finished,
    send,
    complete,
    close: ws.close,
    open: ws.open,
  }
}

async function generateAiResponseAuthorization(requestBody?: Partial<SignAiDto>): Promise<APIReturn<string>> {
  const body: SignAiDto = {
    host: 'spark-api.xf-yun.com',
    date: new Date().toUTCString(),
    ...requestBody,
  }
  const formData = serialize(body)
  return await request.post('/aiResponse/sign', formData)
}

export async function getAiChatWebSocket() {
  const host = 'spark-api.xf-yun.com'
  const date = new Date().toUTCString()
  const authorization = (await generateAiResponseAuthorization(
    {
      host,
      date,
    },
  )).data.data

  const ws = useWebSocket(`wss://spark-api.xf-yun.com/v3.1/chat?authorization=${authorization}&date=${date}&host=${host}`)

  const content = ref('')

  const finished = ref(false)

  watch(ws.data, (newVal) => {
    const res = JSON.parse(newVal)
    if (res.header.code === 0) {
      content.value += res.payload.choices.text[0].content
      // console.log(`receive message: ${content.value}`)
      if (res.payload.choices.status === 2)
        finished.value = true
    }
    else { console.log(res) }
  })

  function send(messages: Message[]) {
    const body = {
     header: {
        app_id: 'f5132e66',
      },
      parameter: {
        chat: {
          domain: 'generalv3',
          temperature: 0.5,
          max_tokens: 2048,
        },
      },
      payload: {
        message: {
          text: [
            ...messages,
            {
              content: '以上是一段未完成的对话，现在你要扮演角色assistant，为了让对话能够进行下去，你需要回复user。回复策略为表示理解用户user的话，并换一种说法重复肯定user说的话，并尝试启发user继续表达，提出一个问句以继续对话。现在请开始你的任务，你只需要给出assistant的回复，不需要给出多余的话',
              role: 'user',
            },
          ],
        },
      },
    }
    ws.send(JSON.stringify(body))
  }

  return {
    content,
    status: ws.status,
    finished,
    send,
    close: ws.close,
    open: ws.open,
  }}
